package com.mo.springboot.config;

import com.mo.springboot.entity.Student;
import com.mo.springboot.listener.BaseJobListener;
import com.mo.springboot.process.StudentItemProcessor;
import com.mo.springboot.reader.StudentFieldSetMapper;
import com.mo.springboot.writer.StudentItemWriter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
public class StudentJobConfig {

    /**
     * Job：我们要实际执行的任务，包含一个或多个Step
     *
     * @param jobBuilderFactory
     * @param step
     * @return
     */
    @Bean
    public Job studentJob(JobBuilderFactory jobBuilderFactory, @Qualifier("student_step") Step step) {
        return jobBuilderFactory
                .get("studentJob")
                .incrementer(new RunIdIncrementer())
                .flow(step)
                .end()
                .listener(baseJobListener())
                .build();
    }


    /**
     * Step：Step-步骤包含ItemReader，ItemProcessor和ItemWriter
     *
     * @param stepBuilderFactory
     * @param reader
     * @param writer
     * @param processor
     * @return
     */
    @Bean
    public Step student_step(StepBuilderFactory stepBuilderFactory,
                             @Qualifier("s_reader") ItemReader<Student> reader,
                             @Qualifier("s_writer") ItemWriter<Student> writer,
                             @Qualifier("s_processor") ItemProcessor<Student, Student> processor) {
        // 1.批处理每次提交10条数据。
        return stepBuilderFactory.get("student_step").<Student, Student>chunk(10)
                // 2.给step绑定reader
                .reader(reader)
                // 3.给step绑定processor
                .processor(processor)
                // 4.给step绑定writer
                .writer(writer)
                .build();
    }


    /**
     * ItemReader：用来读取数据的接口
     *
     * @return
     * @throws Exception
     */
    @Bean
    public ItemReader<Student> s_reader() throws IOException {
        // 使用FlatFileItemReader读取文件
        FlatFileItemReader<Student> reader = new FlatFileItemReader<>();
        reader.setLinesToSkip(1);
        reader.setResource(new ClassPathResource("csv/student.csv"));

        // 在此处对cvs文件的数据和领域模型类做对应映射
        reader.setLineMapper(new DefaultLineMapper<Student>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                setNames(new String[]{"id", "name", "sex", "birthDate", "homeAddress", "school", "grade"});
            }});
            setFieldSetMapper(studentFieldSetMapper());
        }});
        return reader;
    }

    /**
     * ItemProcessor：用来处理数据的接口
     *
     * @return
     */
    @Bean
    public ItemProcessor<Student, Student> s_processor() {
        // 使用我们自己定义的ItemProcessor的实现CsvItemProcessor。
        StudentItemProcessor processor = new StudentItemProcessor();
        // 为processor指定校验器为CsvBeanValidator
        //processor.setValidator(csvBeanValidator());
        return processor;
    }

    /**
     * ItemWriter：用来输出数据的接口
     *
     * @param dataSource
     * @return
     */
    @Bean
    public ItemWriter<Student> s_writer(DataSource dataSource) {
        // 我们使用JDBC批处理的JdbcBatchItemWriter来写数据到数据库。
        StudentItemWriter writer = new StudentItemWriter();
        return writer;
    }


    /**
     * 自定义监听器
     *
     * @return
     */
    @Bean
    public BaseJobListener baseJobListener() {
        return new BaseJobListener();
    }


    /**
     * 自定义校验器
     *
     * @return
     */
    /*@Bean
    public Validator<Student> csvBeanValidator() {
        return new CsvBeanValidator<>();
    }*/

    /**
     * 自定义lineMapper
     *
     * @return
     */
    @Bean
    public StudentFieldSetMapper studentFieldSetMapper() {
        return new StudentFieldSetMapper();
    }

}
